#include "sgw_device.h"
#include <json-c/json.h>
#include <stdio.h>
#include "mod_gpio.h"
#include "aexgpio.h"
#include "aexudp.h"

PSGWDEVICE g_devices_head;

/**
 * 在链表末尾添加新设备
 */
PSGWDEVICE sgw_add_device()
{
    PSGWDEVICE psgw = g_devices_head;//(PSGWDEVICE)malloc(sizeof(SGWDEVICE));

    if(psgw == NULL){
        g_devices_head = (PSGWDEVICE)malloc(sizeof(SGWDEVICE));
        if(g_devices_head)
            memset(g_devices_head,0,sizeof(SGWDEVICE));
        return g_devices_head;
    }else{
        while (psgw->next != NULL)
        {
            psgw = psgw->next;
        }
        psgw->next = (PSGWDEVICE)malloc(sizeof(SGWDEVICE));
        if(psgw->next)
            memset(psgw->next,0,sizeof(SGWDEVICE));
        return psgw->next;
    }
    return NULL;
}

/**
 * 清除所有设备
 */
void sgw_clear_devices()
{
    PSGWDEVICE psgw = g_devices_head;

    while(g_devices_head && g_devices_head->next){
        psgw = g_devices_head;
        g_devices_head = psgw->next;
        free(psgw);
    }
}

/**
 * 从JSON文件获取设备的列表，如果文件格式不对，或者额没有获取到设备返回0
 */
int sgw_load_devices_from(char *fn)
{
    struct json_object *jdevices = json_object_from_file(fn);
    struct json_object *devices;
    hcs_hint("%s:%s\n",__func__,fn);
    sgw_clear_devices();
    if(json_object_object_get_ex(jdevices, "devices", &devices)){
        hcs_hint("%s:%d\n",__func__,__LINE__);
        json_type type = json_object_get_type(devices);// 先获取json对象类型
        hcs_hint("%s:%d\n",__func__,__LINE__);
        if(json_type_array == type){
            int i=0;
            for(i=0; i <json_object_array_length(devices); i++) {
                struct json_object *device =json_object_array_get_idx(devices, i);

                if(json_type_object == json_object_get_type(device)){
                    PSGWDEVICE psgw = sgw_add_device();
                    if(psgw != NULL){
                        struct json_object *obj = json_object_object_get(device,"id");
                        psgw->id = json_object_get_int(obj);
                        json_object_put(obj);
                        obj = json_object_object_get(device,"type");
                        psgw->type = json_object_get_int(obj);
                        json_object_put(obj);
                        obj = json_object_object_get(device,"solt");
                        psgw->slot = json_object_get_int(obj);
                        json_object_put(obj);
                        obj = json_object_object_get(device,"hasnet");
                        psgw->hasNet = json_object_get_int(obj);
                        json_object_put(obj);
                    }
                }
                json_object_put(device);
            }
        }    
        json_object_put(devices);
    }
    json_object_put(jdevices);
}

int sgw_save_devices_tobuf(char *buf,int len)
{
    PSGWDEVICE psgw = g_devices_head;
    char *pbuf = buf;
    int ret = snprintf(pbuf,len-1,"{\n\t\"devices\":[\n");
    while(psgw){
        len -= ret;
        pbuf += ret;
        ret = snprintf(pbuf,len-1,"{\"id\":%d,\"type\":%d,\"slot\":%d,\"hasnet\":%d,\"bus\":%d,\"online\":%d,\"error\":%d},\n",
            psgw->id,psgw->type,psgw->slot,psgw->hasNet,psgw->bus,psgw->online,psgw->error);
        psgw = psgw->next;
    }
    
    len -= ret;
    pbuf += ret;
    ret = snprintf(pbuf,len-1,"\n\t]\n}\n ");
    pbuf += ret;
    *pbuf = '\0';
    return strlen(buf);
}

int sgw_save_devices_tofile(char *fn)
{
    char buf[1024];
    FILE *file;
    int ret = 0;

    file = fopen(fn,"w+");
    if(file == NULL){
        ret = sgw_save_devices_tobuf(buf,sizeof(buf));
        fwrite(buf,1,ret,file);
        fclose(file);
    }

    return ret;
}

void sgw_device_init()
{
    char buf[1024];
    hcs_config *psudata = get_hcs_data();

    hcs_hint("%s:%s\n",__func__,psudata->devices_fn);
    if(!sgw_load_devices_from(psudata->devices_fn)){
        hcs_error("Load devices from %s fail.\n",psudata->devices_fn);
    }
    sgw_save_devices_tobuf(buf,sizeof(buf));
    hcs_hint("Load devices:%s\n%s\n",psudata->devices_fn,buf);
    {
        PPKTPROPO handle = aexudp_get_default_prkpropo();
        if(handle){
            hcs_hint("AEXUDP:0x%02X,0x%02X\n",handle->start,handle->end);
        }else{
            hcs_error("Not find prkpropo.\n");
        }
    }
}

unsigned char sgw_get_status()
{
	unsigned char ret = 0;
	int index=0;

	ret |= aexgpio_onboard_get(SGWEC_LED_BUS)<<index++;
	ret |= aexgpio_onboard_get(SGWEC_LED_ONLINE)<<index++;
	ret |= aexgpio_onboard_get(SGWEC_LED_ERROR)<<index++;
	ret |= aexgpio_onboard_get(SGWEC_CH1_SEL)<<index++;
	ret |= aexgpio_onboard_get(SGWEC_CH2_SEL)<<index++;
    return ret;
}
/**
 * 设置BUS总线是否有效
 */
void sgw_set_bus(unsigned char bus)
{
    aexgpio_onboard_set(SGWEC_LED_BUS,bus);
}

/**
 * 设置设备是否在线
 */
void sgw_set_online(unsigned char online)
{
    aexgpio_onboard_set(SGWEC_LED_ONLINE,online);
}

/**
 * 设置设备是否有故障
 */
void sgw_set_error(unsigned char error)
{
    aexgpio_onboard_set(SGWEC_LED_ERROR,error);
}
